package com.javamsg.ui;

import static com.javamsg.CommonConstant.OPEN_FILTER_EXTENSIONS;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;

import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;

import com.javamsg.beans.SystemData;

public class PreferenceDialog {
	private static final Logger logger = Logger.getRootLogger(); 
	private static final SystemData data = SystemData.instance();
	
	private final static String TITLE = "Preference Dialog";
	
	
	private final static String[] tabString = {"Person Info", "System Setting"};
	private final static String[] SUPPORT_ENCODEING = {
										"UTF-8",
										"GB2312",
								        "GBK",   
								        "BIG5",      
								        "Unicode",   
								        "EUC_KR",   
								        "SJIS",   
								        "EUC_JP",   
								        "ASCII",   
								        "ISO8859_1", 
								        "GB18030"
										};
	
	private Shell shell;
	private Display display;
	
	private TabFolder tabFolder;
	
	private Image avatarIcon;
	private Text nickNameText;
	private Text ipAddressText;
	private Text signText;
	private Button imageButton;
	private int imageHeight = 100;
	private int imageWidth = 100;
	
	private Combo encodingCombo;
	
	private String imageName = data.getAvatarIcon() ;		// indicates user's avatar icon name
	
	public PreferenceDialog(){
		//this.display = display;
	}
	
	public Shell open(Display _display){
		shell = new Shell(_display);
		shell.setText(TITLE);
		buildWindow();
		shell.setSize(600, 400);
		// move this window to the center of the monitor
		moveWindowToCenter();
		shell.open();
		return shell;
	}
	
	public void setLocation(int x, int y){
		shell.setLocation(x, y);
	}
	
	private void buildWindow(){
		GridLayout layout = new GridLayout();
		layout.numColumns = 1;
		shell.setLayout(layout);
		// top part use a tab
		createTopPart();
		// bottom part contains buttons
		createBottomPart();
	}
	
	private void createTopPart(){
		tabFolder = new TabFolder(shell, SWT.TOP | SWT.BORDER | SWT.FLAT);
		GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
		tabFolder.setLayoutData(gridData);
		
		
		addPersonInfoTabItem(tabFolder);
		addSystemSettingTabItem(tabFolder);
	}
	
	private void addPersonInfoTabItem(TabFolder folder){
		TabItem item = new TabItem(folder, SWT.NONE);
		
		Composite composite = new Composite(folder, SWT.NONE);
		GridLayout layout= new GridLayout();
		layout.numColumns = 2;
		composite.setLayout(layout);
		
		// create left region
		Group leftRegion = new Group(composite, SWT.NONE);
		GridLayout leftRegionLayout = new GridLayout();
		leftRegionLayout.numColumns = 1;
		leftRegion.setLayout(leftRegionLayout);
		GridData leftRegionData = new GridData(SWT.FILL, SWT.FILL, false, true);
		leftRegion.setLayoutData(leftRegionData );
		
		imageButton = new Button(leftRegion, SWT.PUSH);
		GridData imageData = new GridData(SWT.FILL, SWT.TOP, false, false);
		imageData.minimumHeight = 150 ;
		imageData.minimumWidth = 100;
		imageButton.setLayoutData(imageData);
		avatarIcon = new Image(display, imageName );
		
		ImageData oldData = avatarIcon.getImageData();
		ImageData newData = oldData.scaledTo( imageHeight, imageWidth );

		avatarIcon = new Image(display, newData);
		
		imageButton.setImage(avatarIcon);
		imageButton.setSize(100, 100);
		imageButton.setToolTipText("Change Icon...");
		imageButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				changeIcon();
			}
		});
		Button changeImageButton = new Button(leftRegion, SWT.PUSH);
		changeImageButton.setText("Change Icon");
		changeImageButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				changeIcon();
			}
		});
		
		// create right region
		Group rightRegion = new Group(composite, SWT.NONE);
		GridData rightRegionData = new GridData(SWT.FILL, SWT.FILL, true, true);
		rightRegion.setLayoutData(rightRegionData);
		GridLayout rightRegionLayout = new GridLayout();
		rightRegionLayout.numColumns = 4;
		rightRegion.setLayout(rightRegionLayout);
		
		GridData span2GridData = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
		span2GridData.horizontalSpan = 2;
		
		GridData span4GridData = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
		span4GridData.horizontalSpan = 4;
		
		Label nickNameLabel = new Label(rightRegion, SWT.NONE);
		nickNameLabel.setText("NickName");
		nickNameLabel.setLayoutData(span2GridData);
		
		Label ipAddressLabel = new Label(rightRegion, SWT.NONE);
		ipAddressLabel.setText("IP Address");
		ipAddressLabel.setLayoutData(span2GridData);

		GridData textSpan2GridData = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
		textSpan2GridData.horizontalSpan = 2;
		
		nickNameText = new Text(rightRegion, SWT.SINGLE | SWT.BORDER );
		nickNameText.setText(data.getNickName());
		nickNameText.setLayoutData(textSpan2GridData);
		
		ipAddressText = new Text(rightRegion, SWT.SINGLE | SWT.BORDER);
		ipAddressText.setEditable(false);
		ipAddressText.setLayoutData(textSpan2GridData);
		
		Label signLabel = new Label(rightRegion, SWT.NONE);
		signLabel.setText("Sign");
		signLabel.setLayoutData(span4GridData);
		
		GridData textSpan4GridData = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
		textSpan4GridData.horizontalSpan = 4;
		textSpan4GridData.heightHint = 40;
		
		signText = new Text(rightRegion, SWT.MULTI | SWT.BORDER);
		signText.setText("Sign");
		signText.setLayoutData(textSpan4GridData);
		signText.setTextLimit(50);
		
		item.setText("Person Info");
		item.setToolTipText("Setting Person Information");
		item.setControl(composite);
	}
	private void addSystemSettingTabItem(TabFolder folder){
		TabItem item = new TabItem(folder, SWT.NONE);
		
		Composite composite = new Composite(folder, SWT.NONE);
		GridLayout layout= new GridLayout();
		layout.numColumns = 2;
		composite.setLayout(layout);
		
		encodingCombo = new Combo(composite, SWT.READ_ONLY | SWT.DROP_DOWN | SWT.BORDER);
		encodingCombo.setItems(SUPPORT_ENCODEING);
		encodingCombo.setText(data.getEncoding());
		
		
		item.setText("System Setting");
		item.setToolTipText("Setting Person Information");
		item.setControl(composite);
	}
	
	private void createBottomPart(){
		Composite composite = new Composite(shell, SWT.NONE);
		GridData gridData = new GridData(SWT.FILL, SWT.BOTTOM, true, false);
		gridData.horizontalSpan = 2;
		composite.setLayoutData(gridData);
		GridLayout layout = new GridLayout();
		layout.numColumns = 4;
		composite.setLayout(layout);
		
		Label infoLabel = new Label(composite, SWT.NONE);
		infoLabel.setText(" ");
		GridData labelGridData = new GridData();
		labelGridData.grabExcessVerticalSpace = false;
		labelGridData.grabExcessHorizontalSpace = true;
		infoLabel.setLayoutData(labelGridData);
		
		Button okButton = new Button(composite, SWT.PUSH);
		okButton.setText("OK");
		okButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				// TODO
				applyChanges();
				shell.close();
			}
		});
		Button cancelButton = new Button(composite, SWT.PUSH);
		cancelButton.setText("Cancel");
		cancelButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				shell.close();
			}
		});
		Button applyButton = new Button(composite, SWT.PUSH);
		applyButton.setText("Apply");
		applyButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				// TODO
				applyChanges();
			}
		});
	}
	/**
	 * change user's avatar icon
	 */
	private void changeIcon(){
		// show a file dialog, let user choose a image as avatar icon
		// copy this photo to local directory
		FileDialog fileDialog = new FileDialog(shell, SWT.OPEN);

		fileDialog.setFilterExtensions(OPEN_FILTER_EXTENSIONS);
		String fileName = fileDialog.open();
		logger.debug("File Path : " + fileName);
		if (fileName != null) {
			try{
				Image iconImage = new Image(display, fileName);
				
				// if image is too big, scale this image
				ImageData oldData = iconImage.getImageData();
				ImageData newData = oldData.scaledTo( imageHeight, imageWidth);
				iconImage = new Image(display, newData);
				imageButton.setImage(iconImage);
				imageName = fileName;
			}catch(Exception e){
				MessageBox warningBox = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK);
				warningBox.setText("Warning!");
				warningBox.setMessage("Save Icon Failed!");
				warningBox.open();
			}
		}
	}
	/**
	 * apply changes
	 */
	private void applyChanges(){
		if(copyImage(imageName)){
			data.setAvatarIcon(imageName);
		}
		data.setNickName(nickNameText.getText());
		// setting signature is available now
		data.setEncoding(encodingCombo.getText());
	}
	/**
	 * copy image to system path
	 * @param fileName
	 * @return
	 */
	private boolean copyImage(String fileName){
		if(fileName == null || fileName.equals(data.getAvatarIcon())){
			return false;
		}
		try{
			// copy this image to system path
			File iconFile = new File(fileName);
			File toFile = new File(iconFile.getName());
			if(toFile.exists()){
				toFile.delete();
			}
			toFile.createNewFile();
			
			FileInputStream in = new FileInputStream(iconFile);
			FileOutputStream out = new FileOutputStream(toFile);
			
			FileChannel srcChannel = in.getChannel();
			FileChannel destChannel = out.getChannel();
			
			destChannel.transferFrom(srcChannel, 0, srcChannel.size());
			srcChannel.close();
			destChannel.close();
			imageName = iconFile.getName();
		}catch(IOException ioe){
			logger.error("Error when copy avatar icon", ioe);
			MessageBox warningBox = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK);
			warningBox.setText("Warning!");
			warningBox.setMessage("Save Icon Failed!");
			warningBox.open();
			return false;
		}
		return true;
	}
	
	/**
	 * move the window to the center of the monitor
	 */
	private void moveWindowToCenter(){
		Monitor monitor = this.shell.getMonitor();
		Rectangle bounds = monitor.getBounds();
		Rectangle rect = shell.getBounds();         
	    int x = bounds.x + (bounds.width - rect.width) / 2;          
	    int y = bounds.y + (bounds.height - rect.height) / 2;          
	    shell.setLocation (x, y);          
	}
	
	
	public static void main(String[] args){
		PreferenceDialog dialog = new PreferenceDialog();
		Display display = new Display();
		Shell shell = dialog.open(display);
		while(!shell.isDisposed()){
			if(!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}
	
}
